package com.gitee.l0km.codegen.decorator.plugin;

import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;

import com.gitee.l0km.codegen.base.CodeGenUtils;
import com.gitee.l0km.codegen.base.plugin.BasePlugin;
import com.gitee.l0km.codegen.decorator.DecoratorConfiguration;
import com.gitee.l0km.codegen.decorator.MXBeanConfiguration;
import com.gitee.l0km.codegen.decorator.MXBeanGenerator;
import com.google.common.collect.ImmutableMap;

/**
 * {@link MXBeanGenerator}生成器运行插件,生成java bean 对应的 MXBean 接口
 * @author guyadong
 *
 */
@Mojo(name = "mxbean",defaultPhase=LifecyclePhase.COMPILE,requiresDependencyResolution=ResolutionScope.COMPILE)
public class MXBeanPlugin extends BasePlugin{
	/**
	 * reference class name
	 */
	@Parameter(required = true)
	private String refClass = null;
	/**
	 * The target package name
	 */
	@Parameter(alias="package",required =true)
	private String pkg ;
	/**
	 * path list of source separated by semicolon
	 */
	@Parameter()
	private String sourcePath;
	/**
	 * exclude templates which will be skip for generation,splited with [,]without blank space
	 */
	@Parameter()
	private String excludeVMs;
	/**
	 * include templates for generation,splited with [,]without blank space
	 */
	@Parameter()
	private String includeVMs;

	/**
	 * Specifies the paths where javadoc will look for referenced classes (.class files),
	 * Ignored since 3.3.0
	 */
	@Parameter()
	private String classPath;
	/**
	 * exclude service methods names,splited with [,]without blank space
	 */
	@Parameter(property="codegen.decorator.excludeMethods")
	private Map<String,String> excludeMethods = ImmutableMap.of();
	/**
	 * include service methods names,splited with [,]without blank space
	 */
	@Parameter(property="codegen.decorator.includeMethods")
	private Map<String,String> includeMethods = ImmutableMap.of();
	/**
	 * exclude fields for struct class name,such {@code '<com.simple.class.ClassA>fieldname1,fieldname2</com.simple.class.ClassA>'} 
	 */
	@Parameter(property="codegen.decorator.excludeFields")
	private Map<String,String> excludeFields = ImmutableMap.of();
	/**
	 * include fields for class name,such {@code '<com.simple.class.ClassA>fieldname1,fieldname2</com.simple.class.ClassA>'} 
	 */
	@Parameter(property="codegen.decorator.excludeFields")
	private Map<String,String> includeFields = ImmutableMap.of();
	/**
	 * include class's member names [METHOD,FIELD],splitting with [,],default [FIELD]
	 */
	@Parameter(property="codegen.decorator.members",defaultValue=MXBeanConfiguration.MEMBER_FIELD)
	private String members;
	public MXBeanPlugin() {
	}

	@Override
	protected String getTemplateFolder() {
		return MXBeanConfiguration.DECORATOR_FOLDER;
	}

	@Override
	public void execute() throws MojoExecutionException, MojoFailureException {
		try {
			MXBeanGenerator.main(makeArgs().toArray(new String[0]));
		} catch (Exception e) {
			throw new MojoExecutionException(e.getMessage(),e);
		}
	}

	@Override
	protected List<String> makeArgs() {
		List<String> args = super.makeArgs();
		args.add("--" + DecoratorConfiguration.PACKAGE_OPTION_LONG);
		args.add(pkg);
		if(null != refClass){
			args.add("--" + DecoratorConfiguration.REFERENCE_CLASS_OPTION_LONG);
			args.add(refClass);
		}
		if(null != sourcePath){
			args.add("--" + DecoratorConfiguration.SOURCE_PREFIX_OPTION_LONG);
			args.add(sourcePath);
		}
		if(null != excludeVMs){
			args.add("--" + DecoratorConfiguration.EXCLUDE_VMS_OPTION_LONG);
			args.add(excludeVMs);
		}
		if(null != includeVMs){
			args.add("--" + DecoratorConfiguration.INCLUDE_VMS_OPTION_LONG);
			args.add(includeVMs);
		}
		classPath = buildClasspath();
		args.add("--" + DecoratorConfiguration.CLASS_PATH_OPTION_LONG);
		args.add(classPath);
		/** 初始项目ClassLoader */
		CodeGenUtils.initProjectClassLoader(classPath, getClass().getClassLoader());
		if(!excludeMethods.isEmpty()){
			for(Entry<String, String> entry:excludeMethods.entrySet()){
				args.add("--" + MXBeanConfiguration.EXCLUDE_METHODS_OPTION_LONG);
				args.add(entry.getKey() + ":" + entry.getValue());
			}
		}
		if(!includeMethods.isEmpty()){
			for(Entry<String, String> entry:includeMethods.entrySet()){
				args.add("--" + MXBeanConfiguration.INCLUDE_METHODS_OPTION_LONG);
				args.add(entry.getKey() + ":" + entry.getValue());
			}
		}

		if(!excludeFields.isEmpty()){
			for(Entry<String, String> entry:excludeFields.entrySet()){
				args.add("--" + MXBeanConfiguration.EXCLUDE_FIELDS_OPTION_LONG);
				args.add(entry.getKey() + ":" + entry.getValue());
			}
		}
		if(members != null){
			args.add("--" + MXBeanConfiguration.MEMBERS_OPTION_LONG);
			args.add(members);
		}
		return args;
	}

}
